package com.hjq.demo.ui.activity

import android.Manifest
import android.animation.ValueAnimator
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import cn.cucsi.myframe.R
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe
import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener
import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.flyjingfish.android_aop_core.annotations.SingleClick
import com.hjq.demo.aop.Log
import com.hjq.demo.app.AppActivity
import com.hjq.demo.manager.FullyGridLayoutManager
import com.hjq.demo.other.GlideEngine
import com.hjq.demo.other.ImageLoaderUtils
import com.hjq.demo.other.UCropUtils
import com.hjq.demo.other.vibrate
import com.hjq.demo.ui.adapter.MultimediaGridAdapter
import com.luck.lib.camerax.CustomCameraConfig
import com.luck.lib.camerax.SimpleCameraX
import com.luck.lib.camerax.listener.OnSimpleXPermissionDeniedListener
import com.luck.lib.camerax.listener.OnSimpleXPermissionDescriptionListener
import com.luck.lib.camerax.permissions.SimpleXPermissionUtil
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.decoration.GridSpacingItemDecoration
import com.luck.picture.lib.dialog.RemindDialog
import com.luck.picture.lib.engine.CompressFileEngine
import com.luck.picture.lib.engine.CropFileEngine
import com.luck.picture.lib.engine.ImageEngine
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnCameraInterceptListener
import com.luck.picture.lib.interfaces.OnExternalPreviewEventListener
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.utils.DateUtils
import com.luck.picture.lib.utils.DensityUtil
import com.yalantis.ucrop.UCrop
import com.yalantis.ucrop.UCropImageEngine
import timber.log.Timber
import top.zibin.luban.CompressionPredicate
import top.zibin.luban.Luban
import top.zibin.luban.OnNewCompressListener
import java.io.File


/**
 *    author : Yang
 *    time   : 2024/05/24
 *    desc   : 多媒体相关页面
 *    TODO 获取权限时，需要获取全部媒体文件权限，否则在android14上会弹出系统选择页面和自定义选择页面两个页面
 */
class MultimediaActivity : AppActivity() {

    private var imageEngine: ImageEngine? = null
    private var recycler: RecyclerView? = null
    private var mAdapter: MultimediaGridAdapter? = null

    private val quickDragAndSwipe = QuickDragAndSwipe()
        .setDragMoveFlags(
            ItemTouchHelper.UP or ItemTouchHelper.DOWN or
                    ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
        )
        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)

    override fun getLayoutId(): Int {
        return R.layout.multimedia_activity
    }

    override fun initView() {
        setOnClickListener(
            R.id.btn_mine_custom_multimedia_select,
            R.id.btn_mine_system_multimedia_select,
            R.id.btn_mine_custom_open_camera,
            R.id.btn_mine_system_open_camera,
            R.id.btn_mine_open_preview,
            R.id.btn_mine_image_compression,
            R.id.btn_mine_image_clipper_rectangle,
            R.id.btn_mine_image_clipper_circle
        )

        imageEngine = GlideEngine.createGlideEngine()
        initRecycler()

    }

    private fun initRecycler() {
        recycler = findViewById(R.id.recycler)


        val manager = FullyGridLayoutManager(
            this, 4, GridLayoutManager.VERTICAL, false
        )
        recycler?.setLayoutManager(manager)
        val itemAnimator: RecyclerView.ItemAnimator? = recycler?.itemAnimator
        if (itemAnimator != null) {
            (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
        }
        recycler?.addItemDecoration(
            GridSpacingItemDecoration(
                4, DensityUtil.dip2px(this, 8f), false
            )
        )

        mAdapter = MultimediaGridAdapter()
        mAdapter?.addOnItemChildClickListener(R.id.fiv) { adapter, view, position ->
            PictureSelector.create(this).openPreview()
                .setImageEngine(imageEngine)
                .setExternalPreviewEventListener(object : OnExternalPreviewEventListener {
                    override fun onPreviewDelete(position: Int) {

                    }

                    override fun onLongPressDownload(
                        context: Context?, media: LocalMedia?
                    ): Boolean {
                        return false
                    }
                }).startActivityPreview(
                    position, false, mAdapter?.items as java.util.ArrayList<LocalMedia>?
                )
        }
        // 点击删除按钮，从列表中删除对应的文件
        mAdapter?.addOnItemChildClickListener(R.id.iv_del) { adapter, view, position ->
            if (position != RecyclerView.NO_POSITION && adapter.itemCount > position) {
                adapter.removeAt(position)
            }
        }

        recycler?.setAdapter(mAdapter)

        // 拖拽监听
        val listener: OnItemDragListener = getItemDragListener()
        val swipeListener: OnItemSwipeListener = getItemSwipeListener()

        // 滑动事件
        quickDragAndSwipe.attachToRecyclerView(recycler!!)
            .setDataCallback(mAdapter!!)
            .setItemDragListener(listener)
            .setItemSwipeListener(swipeListener)
    }

    private fun getItemSwipeListener(): OnItemSwipeListener {
        val swipeListener: OnItemSwipeListener = object : OnItemSwipeListener {
            override fun onItemSwipeStart(
                viewHolder: RecyclerView.ViewHolder?,
                bindingAdapterPosition: Int
            ) {
                Timber.i("onItemSwipeStart")
            }

            override fun onItemSwipeEnd(
                viewHolder: RecyclerView.ViewHolder,
                bindingAdapterPosition: Int
            ) {
                Timber.i("onItemSwipeEnd")
            }

            override fun onItemSwiped(
                viewHolder: RecyclerView.ViewHolder,
                direction: Int,
                bindingAdapterPosition: Int
            ) {
                Timber.i("onItemSwiped")
            }

            override fun onItemSwipeMoving(
                canvas: Canvas,
                viewHolder: RecyclerView.ViewHolder,
                dX: Float,
                dY: Float,
                isCurrentlyActive: Boolean
            ) {
                Timber.i("onItemSwipeMoving")
            }
        }
        return swipeListener
    }

    private fun getItemDragListener(): OnItemDragListener {
        val listener: OnItemDragListener = object : OnItemDragListener {
            override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {
                vibrate()
                Timber.i("drag start")
                val holder = viewHolder as QuickViewHolder? ?: return
                // 开始时，item背景色变化，demo这里使用了一个动画渐变，使得自然
                val startColor = Color.WHITE
                val endColor = Color.rgb(245, 245, 245)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    val v = ValueAnimator.ofArgb(startColor, endColor)
                    v.addUpdateListener { animation: ValueAnimator ->
                        holder.itemView.setBackgroundColor(
                            animation.animatedValue as Int
                        )
                    }
                    v.duration = 300
                    v.start()
                }
            }

            override fun onItemDragMoving(
                source: RecyclerView.ViewHolder,
                from: Int,
                target: RecyclerView.ViewHolder,
                to: Int
            ) {
                Timber.i(
                    "move from: " + source.bindingAdapterPosition + " to: " + target.bindingAdapterPosition
                )
            }

            override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {
                Timber.i("drag end")
                val holder = viewHolder as QuickViewHolder
                // 结束时，item背景色变化，demo这里使用了一个动画渐变，使得自然
                val startColor = Color.rgb(245, 245, 245)
                val endColor = Color.WHITE
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    val v = ValueAnimator.ofArgb(startColor, endColor)
                    v.addUpdateListener { animation: ValueAnimator ->
                        holder.itemView.setBackgroundColor(
                            animation.animatedValue as Int
                        )
                    }
                    v.duration = 300
                    v.start()
                }

                mAdapter?.items?.forEach {
                    Timber.i(
                        "-------->> w 顺序 ${it} "
                    )
                }

            }
        }
        return listener
    }

    override fun initData() {}

    @SingleClick
    override fun onClick(view: View) {
        when (view.id) {
            R.id.btn_mine_custom_multimedia_select -> {

                PictureSelector.create(this).openGallery(SelectMimeType.ofAll())
                    .setImageEngine(imageEngine).isWithSelectVideoImage(true)
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }

            R.id.btn_mine_system_multimedia_select -> {

                PictureSelector.create(this).openSystemGallery(SelectMimeType.ofAll())
                    .forSystemResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }

            R.id.btn_mine_custom_open_camera -> {

                PictureSelector.create(this).openCamera(SelectMimeType.ofAll())
                    .setCameraInterceptListener(MeOnCameraInterceptListener())
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }

            R.id.btn_mine_system_open_camera -> {

                PictureSelector.create(this).openCamera(SelectMimeType.ofAll())
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }

            R.id.btn_mine_open_preview -> {

                if (mAdapter?.itemCount == 0) {
                    toast("请先选择图片")
                    return
                }

                PictureSelector.create(this).openPreview()
                    .setImageEngine(imageEngine)
                    .setExternalPreviewEventListener(object : OnExternalPreviewEventListener {
                        override fun onPreviewDelete(position: Int) {

                        }

                        override fun onLongPressDownload(
                            context: Context?, media: LocalMedia?
                        ): Boolean {
                            return false
                        }
                    }).startActivityPreview(
                        0, true, mAdapter?.items as java.util.ArrayList<LocalMedia>?
                    )
            }

            R.id.btn_mine_image_compression -> {
                PictureSelector.create(this).openGallery(SelectMimeType.ofImage())
                    .setImageEngine(imageEngine)
                    .isWithSelectVideoImage(true)
                    .setCompressEngine(ImageFileCompressEngine())
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }

            R.id.btn_mine_image_clipper_rectangle -> {
                val options: UCrop.Options = UCropUtils.buildOptionsRectangle(getContext())
                PictureSelector.create(this).openGallery(SelectMimeType.ofImage())
                    .setImageEngine(imageEngine)
                    .isWithSelectVideoImage(true)
                    .setCropEngine(ImageFileCropEngine(options))
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }

            R.id.btn_mine_image_clipper_circle -> {
                val options: UCrop.Options = UCropUtils.buildOptionsCircle(getContext())
                PictureSelector.create(this).openGallery(SelectMimeType.ofImage())
                    .setImageEngine(imageEngine)
                    .isWithSelectVideoImage(true)
                    .setCropEngine(ImageFileCropEngine(options))
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>) {
                            if (mAdapter?.itemCount != 0) {
                                mAdapter?.removeAtRange(IntRange(0, mAdapter!!.itemCount))
                            }
                            mAdapter?.addAll(result)
                        }

                        override fun onCancel() {}
                    })
            }
        }
    }

    private class MeOnCameraInterceptListener : OnCameraInterceptListener {
        override fun openCamera(fragment: Fragment, cameraMode: Int, requestCode: Int) {
            val camera = SimpleCameraX.of()
            camera.isAutoRotation(true)
            camera.setCameraMode(CustomCameraConfig.BUTTON_STATE_BOTH)
            camera.setVideoFrameRate(25)
            camera.setVideoBitRate(3 * 1024 * 1024)
            camera.isDisplayRecordChangeTime(true)
            camera.isManualFocusCameraPreview(true) // 是否手动点击对焦
            camera.isZoomCameraPreview(true) // 是否可缩放相机
            camera.setPermissionDeniedListener(MeOnSimpleXPermissionDeniedListener())
            camera.setPermissionDescriptionListener(MeOnSimpleXPermissionDescriptionListener())
            camera.setImageEngine { context, url, imageView ->
                Glide.with(context).load(url).into(imageView)
            }
            camera.start(fragment.requireActivity(), fragment, requestCode)
        }
    }


    /**
     * 拒绝权限请求
     */
    private class MeOnSimpleXPermissionDeniedListener : OnSimpleXPermissionDeniedListener {
        override fun onDenied(context: Context, permission: String, requestCode: Int) {
            val tips = if (TextUtils.equals(permission, Manifest.permission.RECORD_AUDIO)) {
                "缺少麦克风权限\n可能会导致录视频无法采集声音"
            } else {
                "缺少相机权限\n可能会导致不能使用摄像头功能"
            }
            val dialog = RemindDialog.buildDialog(context, tips)
            dialog.setButtonText("去设置")
            dialog.setButtonTextColor(-0x828201)
            dialog.setContentTextColor(-0xcccccd)
            dialog.setOnDialogClickListener {
                SimpleXPermissionUtil.goIntentSetting(context as Activity, requestCode)
                dialog.dismiss()
            }
            dialog.show()
        }
    }

    /**
     * 权限说明
     * */
    private class MeOnSimpleXPermissionDescriptionListener :
        OnSimpleXPermissionDescriptionListener {
        @Log
        override fun onPermissionDescription(
            context: Context, viewGroup: ViewGroup, permission: String
        ) {

        }

        @Log
        override fun onDismiss(viewGroup: ViewGroup) {

        }
    }

    /**
     * 自定义压缩
     */
    private class ImageFileCompressEngine : CompressFileEngine {
        override fun onStartCompress(
            context: Context,
            source: java.util.ArrayList<Uri>,
            call: OnKeyValueResultCallbackListener
        ) {
            Luban.with(context).load(source).ignoreBy(100).setRenameListener { filePath ->
                val indexOf = filePath.lastIndexOf(".")
                val postfix = if (indexOf != -1) filePath.substring(indexOf) else ".jpg"
                DateUtils.getCreateFileName("CMP_") + postfix
            }.filter(CompressionPredicate { path ->
                if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) {
                    return@CompressionPredicate true
                }
                !PictureMimeType.isUrlHasGif(path)
            }).setCompressListener(object : OnNewCompressListener {
                override fun onStart() {
                }

                override fun onSuccess(source: String, compressFile: File) {
                    if (call != null) {
                        call.onCallback(source, compressFile.absolutePath)
                    }
                }

                override fun onError(source: String, e: Throwable) {
                    if (call != null) {
                        call.onCallback(source, null)
                    }
                }
            }).launch()
        }
    }

    /**
     * 自定义裁剪
     */
    private class ImageFileCropEngine(val options: UCrop.Options) : CropFileEngine {

        override fun onStartCrop(
            fragment: Fragment,
            srcUri: Uri,
            destinationUri: Uri,
            dataSource: java.util.ArrayList<String>,
            requestCode: Int
        ) {
            val uCrop = UCrop.of(srcUri, destinationUri, dataSource)
            uCrop.withOptions(options)
            uCrop.setImageEngine(object : UCropImageEngine {
                override fun loadImage(context: Context, url: String, imageView: ImageView) {
                    if (!ImageLoaderUtils.assertValidRequest(context)) {
                        return
                    }
                    Glide.with(context).load(url).override(180, 180).into(imageView)
                }

                override fun loadImage(
                    context: Context,
                    url: Uri,
                    maxWidth: Int,
                    maxHeight: Int,
                    call: UCropImageEngine.OnCallbackListener<Bitmap>
                ) {
                    Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight)
                        .into(object : CustomTarget<Bitmap?>() {

                            override fun onResourceReady(
                                resource: Bitmap,
                                transition: Transition<in Bitmap?>?
                            ) {
                                if (call != null) {
                                    call.onCall(resource)
                                }
                            }

                            override fun onLoadCleared(placeholder: Drawable?) {
                                if (call != null) {
                                    call.onCall(null)
                                }
                            }
                        })
                }
            })
            uCrop.start(fragment.requireActivity(), fragment, requestCode)
        }
    }
}